import Cookies from 'js-cookie'
import {
  addClasses,
  loadCSS,
  removeClasses,
  onLocationChangeListener,
} from './DOMHelpers'
import {
  body,
  widgetHolder,
  createBubbleHolder,
  createBubbleIcon,
  bubbleSVG,
  chatBubble,
  closeBubble,
  bubbleHolder,
  createNotificationBubble,
  onClickChatBubble,
  onBubbleClick,
  setBubbleText,
  addUnreadClass,
  removeUnreadClass,
} from './bubbleHelpers'
import { isWidgetColorLighter } from '@/yichat.web.share/helpers/colorHelper'
import { dispatchWindowEvent } from '@/yichat.web.share/helpers/CustomEventHelper'
import {
  CHATWOOT_ERROR,
  CHATWOOT_ON_MESSAGE,
  CHATWOOT_READY,
} from '@/yichat.web.share/constants/sdkEvents'
import { SET_USER_ERROR } from '@/yichat.web.share/constants/errorTypes'
import { getUserCookieName } from './cookieHelpers'
import {
  getAlertAudio,
  initOnEvents,
} from '@/yichat.web.share/helpers/AudioNotificationHelper'
import { isFlatWidgetStyle } from './settingsHelper'
import { popoutChatWindow } from '@/yichat.web.share/helpers/popoutHelper'

const updateAuthCookie = cookieContent =>
  Cookies.set('cw_conversation', cookieContent, {
    expires: 365,
    sameSite: 'Lax',
  })

export const IFrameHelper = {
  getUrl ({ baseUrl, websiteToken, accountId }) {
    return `${baseUrl}/#/?websiteToken=${websiteToken}&accountId=${accountId}`
  },
  createFrame: ({ baseUrl, websiteToken, accountId }) => {
    if (IFrameHelper.getAppFrame()) {
      return
    }

    loadCSS()
    const iframe = document.createElement('iframe')
    const cwCookie = Cookies.get('cw_conversation')
    let widgetUrl = IFrameHelper.getUrl({ baseUrl, websiteToken, accountId })
    if (cwCookie) {
      widgetUrl = `${widgetUrl}&cw_conversation=${cwCookie}`
    }
    iframe.src = widgetUrl
    iframe.allow =
      'camera;microphone;fullscreen;display-capture;picture-in-picture;clipboard-write;'
    iframe.id = 'chatwoot_live_chat_widget'
    iframe.style.visibility = 'hidden'

    let holderClassName = `woot-widget-holder woot--hide woot-elements--${window.$chatwoot.position}`
    if (window.$chatwoot.hideMessageBubble) {
      holderClassName += ` woot-widget--without-bubble`
    }
    if (isFlatWidgetStyle(window.$chatwoot.widgetStyle)) {
      holderClassName += ` woot-widget-holder--flat`
    }

    addClasses(widgetHolder, holderClassName)
    widgetHolder.appendChild(iframe)
    body.appendChild(widgetHolder)
    IFrameHelper.initPostMessageCommunication()
    IFrameHelper.initWindowSizeListener()
    IFrameHelper.preventDefaultScroll()
  },
  getAppFrame: () => document.getElementById('chatwoot_live_chat_widget'),
  getBubbleHolder: () => document.getElementsByClassName('woot--bubble-holder'),
  sendMessage: (key, value) => {
    const element = IFrameHelper.getAppFrame()
    element.contentWindow.postMessage(
      `chatwoot-widget:${JSON.stringify({ event: key, ...value })}`,
      '*'
    )
  },
  initPostMessageCommunication: () => {
    window.onmessage = e => {
      if (
        typeof e.data !== 'string' ||
        e.data.indexOf('chatwoot-widget:') !== 0
      ) {
        return
      }
      const message = JSON.parse(e.data.replace('chatwoot-widget:', ''))
      if (typeof IFrameHelper.events[message.event] === 'function') {
        IFrameHelper.events[message.event](message)
      }
    }
  },
  initWindowSizeListener: () => {
    window.addEventListener('resize', () => IFrameHelper.toggleCloseButton())
  },
  preventDefaultScroll: () => {
    widgetHolder.addEventListener('wheel', event => {
      const deltaY = event.deltaY
      const contentHeight = widgetHolder.scrollHeight
      const visibleHeight = widgetHolder.offsetHeight
      const scrollTop = widgetHolder.scrollTop

      if (
        (scrollTop === 0 && deltaY < 0) ||
        (visibleHeight + scrollTop === contentHeight && deltaY > 0)
      ) {
        event.preventDefault()
      }
    })
  },

  setFrameHeightToFitContent: (extraHeight, isFixedHeight) => {
    const iframe = IFrameHelper.getAppFrame()
    const updatedIframeHeight = isFixedHeight ? `${extraHeight}px` : '100%'

    if (iframe) { iframe.setAttribute('style', `height: ${updatedIframeHeight} !important`) }
  },

  setupAudioListeners: () => {
    const { fileBaseUrl = '' } = window.$chatwoot
    getAlertAudio(fileBaseUrl, { type: 'widget', alertTone: 'ding' }).then(() =>
      initOnEvents.forEach(event => {
        document.removeEventListener(
          event,
          IFrameHelper.setupAudioListeners,
          false
        )
      })
    )
  },

  events: {
    loaded: message => {
      updateAuthCookie(message.config.authToken)
      window.$chatwoot.hasLoaded = true
      IFrameHelper.sendMessage('config-set', {
        locale: window.$chatwoot.locale,
        position: window.$chatwoot.position,
        hideMessageBubble: window.$chatwoot.hideMessageBubble,
        showPopoutButton: window.$chatwoot.showPopoutButton,
        widgetStyle: window.$chatwoot.widgetStyle,
        darkMode: window.$chatwoot.darkMode,
      })
      IFrameHelper.onLoad({
        widgetColor: message.config.channelConfig.widgetColor,
      })
      IFrameHelper.toggleCloseButton()

      if (window.$chatwoot.user) {
        IFrameHelper.sendMessage('set-user', window.$chatwoot.user)
      }

      window.playAudioAlert = () => {}

      initOnEvents.forEach(e => {
        document.addEventListener(e, IFrameHelper.setupAudioListeners, false)
      })

      if (!window.$chatwoot.resetTriggered) {
        dispatchWindowEvent({ eventName: CHATWOOT_READY })
      }
    },
    error: ({ errorType, data }) => {
      dispatchWindowEvent({ eventName: CHATWOOT_ERROR, data: data })

      if (errorType === SET_USER_ERROR) {
        Cookies.remove(getUserCookieName())
      }
    },
    onMessage ({ data }) {
      dispatchWindowEvent({ eventName: CHATWOOT_ON_MESSAGE, data })
    },
    setBubbleLabel (message) {
      setBubbleText(window.$chatwoot.launcherTitle || message.label)
    },

    setAuthCookie ({ data: { widgetAuthToken }}) {
      updateAuthCookie(widgetAuthToken)
    },

    toggleBubble: state => {
      const bubbleState = {}
      if (state === 'open') {
        bubbleState.toggleValue = true
      } else if (state === 'close') {
        bubbleState.toggleValue = false
      }

      onBubbleClick(bubbleState)
    },

    popoutChatWindow: ({ baseUrl, websiteToken, locale }) => {
      const cwCookie = Cookies.get('cw_conversation')
      window.$chatwoot.toggle('close')
      popoutChatWindow(baseUrl, websiteToken, locale, cwCookie)
    },

    closeWindow: () => {
      onBubbleClick({ toggleValue: false })
      removeUnreadClass()
    },

    onBubbleToggle: isOpen => {
      IFrameHelper.sendMessage('toggle-open', { isOpen })
      if (isOpen) {
        IFrameHelper.pushEvent('webwidget.triggered')
      }
    },
    onLocationChange: ({ referrerURL, referrerHost }) => {
      IFrameHelper.sendMessage('change-url', {
        referrerURL,
        referrerHost,
      })
    },
    updateIframeHeight: message => {
      const { extraHeight = 0, isFixedHeight } = message

      IFrameHelper.setFrameHeightToFitContent(extraHeight, isFixedHeight)
    },

    setUnreadMode: () => {
      addUnreadClass()
      onBubbleClick({ toggleValue: true })
    },

    resetUnreadMode: () => removeUnreadClass(),
    handleNotificationDot: event => {
      if (window.$chatwoot.hideMessageBubble) {
        return
      }

      const bubbleElement = document.querySelector('.woot-widget-bubble')
      if (
        event.unreadMessageCount > 0 &&
        !bubbleElement.classList.contains('unread-notification')
      ) {
        addClasses(bubbleElement, 'unread-notification')
      } else if (event.unreadMessageCount === 0) {
        removeClasses(bubbleElement, 'unread-notification')
      }
    },

    closeChat: () => {
      onBubbleClick({ toggleValue: false })
    },

    playAudio: () => {
      window.playAudioAlert()
    },
  },
  pushEvent: eventName => {
    IFrameHelper.sendMessage('push-event', { eventName })
  },

  onLoad: ({ widgetColor }) => {
    const iframe = IFrameHelper.getAppFrame()
    iframe.style.visibility = ''
    iframe.setAttribute('id', `chatwoot_live_chat_widget`)

    if (IFrameHelper.getBubbleHolder().length) {
      return
    }
    createBubbleHolder(window.$chatwoot.hideMessageBubble)
    onLocationChangeListener()

    let className = 'woot-widget-bubble'
    let closeBtnClassName = `woot-elements--${window.$chatwoot.position} woot-widget-bubble woot--close woot--hide`

    if (isFlatWidgetStyle(window.$chatwoot.widgetStyle)) {
      className += ' woot-widget-bubble--flat'
      closeBtnClassName += ' woot-widget-bubble--flat'
    }

    if (isWidgetColorLighter(widgetColor)) {
      className += ' woot-widget-bubble-color--lighter'
      closeBtnClassName += ' woot-widget-bubble-color--lighter'
    }

    const chatIcon = createBubbleIcon({
      className,
      path: bubbleSVG,
      target: chatBubble,
    })

    addClasses(closeBubble, closeBtnClassName)

    chatIcon.style.background = widgetColor
    closeBubble.style.background = widgetColor

    bubbleHolder.appendChild(chatIcon)
    bubbleHolder.appendChild(closeBubble)
    bubbleHolder.appendChild(createNotificationBubble())
    onClickChatBubble()
  },
  toggleCloseButton: () => {
    let isMobile = false
    if (window.matchMedia('(max-width: 668px)').matches) {
      isMobile = true
    }
    IFrameHelper.sendMessage('toggle-close-button', { isMobile })
  },
}
